# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+import traceback
+
import errno
import sys
import socket
print 'xfr_progress>', val
return None
+ def xfr_vm_destroy(self, xfrd, val):
+ print 'xfr_vm_destroy>', val
+ try:
+ vmid = sxp.child0(val)
+ val = self.xd.domain_destroy(vmid)
+ if vmid in self.paused:
+ del self.paused[vmid]
+ if vmid in self.suspended:
+ del self.suspended[vmid]
+ except:
+ val = errno.EINVAL
+ return ['xfr.err', val]
+
def xfr_vm_pause(self, xfrd, val):
print 'xfr_vm_pause>', val
try:
d.addErrback(cberr)
d.setTimeout(self.timeout)
return d
- except:
+ except Exception, err:
+ print 'xfr_vm_suspend> Exception', err
+ traceback.print_exc()
val = errno.EINVAL
return ['xfr.err', val]
@param port: destination port
@return: deferred
"""
- if host in ['localhost', '127.0.0.1']:
- raise XendError('cannot migrate to localhost')
# Check dom for existence, not migrating already.
# Subscribe to migrate notifications (for updating).
xid = self.nextid()
import sys
import struct
+import types
from xen.lowlevel import xu
@rtype: dict
"""
args = msg.get_payload()
- mac = [0, 0, 0, 0, 0, 0]
- macs = []
- for (k, v) in args.items():
- if k.startswith('mac['):
- macs += k
- i = int(k[4:5])
- mac[i] = v
- else:
- pass
- if macs:
- args['mac'] = mac
- for k in macs:
- del args[k]
+ if isinstance(args, types.StringType):
+ args = { 'value': args }
+ else:
+ mac = [0, 0, 0, 0, 0, 0]
+ macs = []
+ for (k, v) in args.items():
+ if k.startswith('mac['):
+ macs += k
+ i = int(k[4:5])
+ mac[i] = v
+ else:
+ pass
+ if macs:
+ args['mac'] = mac
+ for k in macs:
+ del args[k]
if DEBUG:
msgid = msg.get_header()['id']
print '<unpackMsg', msgid, ty, args
Sxpr oxfr_progress; // (xfr.progress <percent> <rate: kb/s>)
Sxpr oxfr_save; // (xfr.save <vmid> <vmconfig> <file>)
Sxpr oxfr_save_ok; // (xfr.save.ok)
+Sxpr oxfr_vm_destroy;// (xfr.vm.destroy <vmid>)
Sxpr oxfr_vm_suspend;// (xfr.vm.suspend <vmid>)
Sxpr oxfr_xfr; // (xfr.xfr <vmid>)
Sxpr oxfr_xfr_ok; // (xfr.xfr.ok <vmid>)
oxfr_progress = intern("xfr.progress");
oxfr_save = intern("xfr.save");
oxfr_save_ok = intern("xfr.save.ok");
+ oxfr_vm_destroy = intern("xfr.vm.destroy");
oxfr_vm_suspend = intern("xfr.vm.suspend");
oxfr_xfr = intern("xfr.xfr");
oxfr_xfr_ok = intern("xfr.xfr.ok");
return err;
}
+int xfr_send_destroy(Conn *conn, uint32_t vmid){
+ int err = 0;
+
+ err = IOStream_print(conn->out, "(%s %d)",
+ atom_name(oxfr_vm_destroy), vmid);
+ return (err < 0 ? err : 0);
+}
+
+/** Destroy a vm on behalf of save/migrate.
+ */
+int xfr_vm_destroy(Conn *xend, uint32_t vmid){
+ int err = 0;
+ dprintf("> vmid=%u\n", vmid);
+ err = xfr_send_destroy(xend, vmid);
+ if(err) goto exit;
+ IOStream_flush(xend->out);
+ err = xfr_response(xend);
+ exit:
+ dprintf("< err=%d\n", err);
+ return err;
+}
+
/** Get vm state. Send transfer message.
*
* @param peer connection
err = xen_domain_snd(xend, peer->out,
state->vmid, state->vmconfig, state->vmconfig_n);
if(err) goto exit;
+ // Sending the domain suspends it, and there's no way back.
+ // So destroy it now. If anything goes wrong now it's too late.
+ err = xfr_vm_destroy(xend, state->vmid);
+ if(err) goto exit;
IOStream_flush(peer->out);
// Read the response from the peer.
err = Conn_sxpr(peer, &sxpr);